package ch.jamme.impl;

import java.util.concurrent.*;

import org.jdom.*;

import ch.jamme.exception.*;
import ch.jamme.reference.*;

class ObjectToXmlConsumer extends ObjectToXmlConvertor implements Runnable {
	
	private BlockingQueue<XmlMarshallableReference> queue;
	
	private JammeException failureException;

	ObjectToXmlConsumer(MarshallerEngine marshallerEngine, BlockingQueue<XmlMarshallableReference> queue) {
		super(marshallerEngine);
		this.queue = queue;
	}
	
	public void run() {
		try {
			while (true) {
				XmlMarshallableReference reference = queue.take();
				if (reference.isVoid()) break; // A void reference is the poison pill that kills this thread
				populateElement(reference.getParentElement(), reference.getValue());
			}
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		} catch (JammeException je) {
			failureException = je;
			throw je;
		}
	}
	
	public JammeException getFailureException() {
		return failureException;
	}
	
	@Override
	protected void processElement(Element parentElement, String elementName, Object object, Object parent) {
		Element processedElement = null;
		Integer objectId = null;
		synchronized (marshallerEngine) {
			processedElement = marshallerEngine.getParsedElement(elementName, object);
			if (processedElement == null) objectId = marshallerEngine.registerParsingObject(object, parent);
		}
		if (processedElement != null && configuration.getMarshallStyle().checkLoops()) processedElement = processNestedObject(elementName, object);
		else if (objectId != null) populateElement(processedElement = new Element(elementName), object, objectId);
		parentElement.addContent(processedElement);
	}
}
